﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.IO.IsolatedStorage;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using Acando.Dynamics.CRM.Silverlight.Library.MetaSdk;
using System.Text;

namespace Acando.Dynamics.CRM.Silverlight.Library.Helper
{
    public class IsolatedStoreHelper
    {

        /** Man kann auch in den IsolationStorgaeSetting speichern!!! 
         * 
         * IsolatedStorageSettings.ApplicationSettings[entityName] = EntityMetaData;
         * IsolatedStorageSettings.ApplicationSettings.Save(); // speichert dauerhat
         */

        public static bool FileExists(string directoryName, string fileName)
        {
            string filePath = String.Format("{0}\\{1}", directoryName, fileName);

            IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication();

            return store.FileExists(filePath);
        }

        /// <summary>
        /// Gets user isolated storage at the application level
        /// </summary>
        /// <returns></returns>
        public static IsolatedStorageFile GetApplicationStore()
        {
            IsolatedStorageFile store = null;

            store = IsolatedStorageFile.GetUserStoreForApplication();

            return store;
        }

        /// <summary>
        /// Gets user isolated storage at the site level 
        /// </summary>
        /// <returns></returns>
        public static IsolatedStorageFile GetSiteStore()
        {
            IsolatedStorageFile store = null;

            store = IsolatedStorageFile.GetUserStoreForSite();

            return store;
        }

        /// <summary>
        /// Write the specified data to the file in the specified directory.
        /// </summary>
        /// <param name="directoryName"></param>
        /// <param name="fileName"></param>
        /// <param name="data"></param>
        public static void StoreData(string directoryName, string fileName, string data)
        {
            var store = GetApplicationStore();

            if (!store.DirectoryExists(directoryName))
                store.CreateDirectory(directoryName);
            

            string filePath = String.Format("{0}\\{1}", directoryName, fileName);

            WriteData<String>(filePath, store, data);   
        }

        public static void StoreDatainAppStore(string directoryName, string fileName, byte[] data)
        {
            IsolatedStorageFile store = GetApplicationStore();

            if (!store.DirectoryExists(directoryName))
                store.CreateDirectory(directoryName);

            string filePath = String.Format("{0}\\{1}", directoryName, fileName);

            if (!store.FileExists(filePath))
                store.CreateFile(filePath);
            

            WriteData<byte[]>(filePath, store, data);
           
        }

        /// <summary>
        /// Get the content of the file
        /// </summary>
        /// <param name="path"></param>
        public static string GetDataFromStore(string directoryName, string fileName)
        {
            var store = GetApplicationStore();
            var filePath = String.Format("{0}\\{1}", directoryName, fileName);
            var contents = String.Empty;

            try
            {
                using (StreamReader reader = new StreamReader(store.OpenFile(filePath, FileMode.Open, FileAccess.Read)))                                          
                {
                    contents = reader.ReadToEnd(); 
                }

                return contents;
            }
            catch (IsolatedStorageException ex)
            {
                //Logging einbauen
                throw ex;
            }

        }

        // ist vielleicht besser:
        private static void WriteSream(Stream stream, System.IO.IsolatedStorage.IsolatedStorageFileStream fileStream)
        {
            byte[] buffer = new byte[4096];
            int bytesRead;

            while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) != 0)
                fileStream.Write(buffer, 0, bytesRead);
                
        
        }

        private static void WriteData<T>(string filePath, IsolatedStorageFile store, T data)
        {
            //using (var store = IsolatedStorageFile.GetUserStoreForApplication())
            //using (var stream = store.CreateFile("hello.txt"))
            //using (var writer = new StreamWriter(stream)) {
            //    writer.Write("Hello World");
    
            try
            {
                using (IsolatedStorageFileStream isoStream = new IsolatedStorageFileStream(filePath, FileMode.Create, store))
                {
                    using (StreamWriter writer = new StreamWriter(isoStream))
                    {
                        writer.Write(data);
                    }
                    
                }
            }
            catch (IsolatedStorageException ex)
            {
                // später noch logging einbauen
                throw ex;
            }
        }

        /// <summary>
        /// Add value to Application Settings dictionary
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public static void AddvalueToApplicationSettings<T>(string key, T value)
        {
            IsolatedStorageSettings siteSettings = null;
            siteSettings = IsolatedStorageSettings.SiteSettings;

            var serial = MetaDataSerializationHelper.Serialize<T>(value);
            var neededSpace = serial.Length;
            var freeSpace = IsolatedStorageFile.GetUserStoreForSite().AvailableFreeSpace;

            if (neededSpace > freeSpace)
            {
                //MessageBox.Show("Please increase IsolatedStorage space!");
            }
            else
            {
                siteSettings[key] = serial;
                siteSettings.Save();
            }
        }

        public static Boolean CurrentSpaceIsLessThan(long targetSpace)
        { 
            long currentSpace = (long)IsolatedStoreHelper.GetCurrentSiteStoreSpace();

            return (currentSpace < targetSpace);
                 
        }

        public static IsolatedStorageSettings GetSiteSettings()
        {
            return IsolatedStorageSettings.SiteSettings;
        }

        public static void AddvalueToSiteSettingsTEST(string key, EntityMetadata value)
        {
            IsolatedStorageSettings siteSettings = null;

            siteSettings = IsolatedStorageSettings.SiteSettings;

            siteSettings[key] = MetaDataSerializationHelper.Serialize(value);
            siteSettings.Save();
            
        }

        /// <summary>
        /// Get value from Application Settings Dictionary
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static T GetValueFromApplicationSettings<T>(string key)
        {
            IsolatedStorageSettings siteSettings = null;

            siteSettings = IsolatedStorageSettings.SiteSettings;

            if (siteSettings.Contains(key))
            {
                var obj = siteSettings[key];
                return MetaDataSerializationHelper.DeserializeXmlTo<T>(obj.ToString());
                //return (T)siteSettings[key];
            }
            else
            {
                throw new Exception( "Key doesn't exist!" );
            }
        }

        /// <summary>
        /// Increase Quota (Popup occurs)
        /// </summary>
        /// <param name="newSize"></param>
        /// <returns></returns>
        public static bool AskUserToIncreaseQuota(long newSize)
        {
            /**The call to IncreaseQuota must be made from a user-initiated event, such as within a handler for a button-click event. 
             * If it is not called from a user-initiated event, Silverlight will not prompt the user and the request will be denied 
             * (the method will return false).*/
            bool result = false;
            long currentSpace = 0;

            //using (var store = IsolatedStorageFile.GetUserStoreForApplication())
            using (var store = IsolatedStorageFile.GetUserStoreForSite())
            {
                currentSpace = store.Quota;
                

                if (currentSpace < newSize)
                {
                    result = store.IncreaseQuotaTo(newSize);
                }
            }

            return result;
        }

        public static List<String> GetAllApplicationSettingsKeys()
        { 
            //IsolatedStorageSettings userSettings = IsolatedStorageSettings.ApplicationSettings;
            IsolatedStorageSettings userSettings = IsolatedStorageSettings.SiteSettings;

            return (from item in userSettings select item.Key).ToList();
        }

        public static long GetCurrentAppStoreSpace()
        {
            using (var store = IsolatedStorageFile.GetUserStoreForApplication())
            {
                return store.Quota;
            }
        }

        public static long GetCurrentSiteStoreSpace()
        {
            using (var store = IsolatedStorageFile.GetUserStoreForSite())
            {
                return store.Quota;
            }
        }

        public static long GetCurrentSiteAvailableFreeSpace()
        {
            return IsolatedStorageFile.GetUserStoreForSite().AvailableFreeSpace;
        }
    }
}
